/*
QAuthentee
Copyright (C) 2010  Pavel Mynarsky <admin@akia.se>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    discoveredDevices = NULL;
    openedDevice = NULL;
    deviceDriver = NULL;
    discoveredFingerprints = NULL;
    enrollDialog = NULL;

    thread = new FprintThread(this);

    deviceComboBox = new QComboBox(this);
    deviceComboBox->setStatusTip(tr("Choose fingerprint device"));
    ui->deviceToolBar->addWidget(deviceComboBox);

    discoverDevices();
    discoverFingerprints();
    openDevice(0);
    createDeviceInfo();

    connect(ui->actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
    connect(ui->actionRemoveAll, SIGNAL(triggered()), this, SLOT(removeAll()));

    connect(deviceComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(openDevice(int)));

    connect(ui->displayWidget, SIGNAL(enroll(int)), this, SLOT(enroll(int)));
    connect(ui->displayWidget, SIGNAL(verify(int)), this, SLOT(verify(int)));
    connect(ui->displayWidget, SIGNAL(remove(int)), this, SLOT(remove(int)));
    // connect(ui->displayWidget, SIGNAL(clicked(int)), this, SLOT(showDetails(int)));
}

MainWindow::~MainWindow()
{
    delete ui;
    fp_dev_close(openedDevice);
    // Make the discovered fingerprints free
    fp_dscv_prints_free(discoveredFingerprints);
    discoveredFingerprints = NULL;
    fp_exit();
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

int MainWindow::discoverDevices()
{
    discoveredDevices = fp_discover_devs();
    nrOfDiscoveredDevices = 0;
    while(discoveredDevices[nrOfDiscoveredDevices] != NULL)
        nrOfDiscoveredDevices++;
    if(discoveredDevices == NULL)
        deviceComboBox->addItem(tr("(no fingerprint devices found)"));
    else
    {
        for(int i = 0; i < nrOfDiscoveredDevices; i++)
        {
            deviceDriver = fp_dscv_dev_get_driver(discoveredDevices[i]);
            deviceComboBox->addItem(QIcon(":/logo/images/logo/authentec_logo.png"), QString(fp_driver_get_full_name(deviceDriver)));
        }
    }

    return nrOfDiscoveredDevices;
}

int MainWindow::discoverFingerprints()
{
    // Clear the previously discovered fingerprints
    fp_dscv_prints_free(discoveredFingerprints);
    discoveredFingerprints = NULL;

    discoveredFingerprints = fp_discover_prints();
    nrOfDiscoveredFingerprints = 0;
    while(discoveredFingerprints[nrOfDiscoveredFingerprints] != NULL)
        nrOfDiscoveredFingerprints++;
    for(int i = 0; i < nrOfDiscoveredFingerprints; i++)
        ui->displayWidget->markEnrolledFingerprints(fp_dscv_print_get_finger(discoveredFingerprints[i]) - 1, true);

    return nrOfDiscoveredFingerprints;
}

void MainWindow::openDevice(int index)
{
    // Close the device before opening another
    fp_dev_close(openedDevice);
    // Open the device
    openedDevice = fp_dev_open(discoveredDevices[index]);
    deviceDriver = fp_dscv_dev_get_driver(*discoveredDevices);
    if(openedDevice == NULL)
    {
         QMessageBox::critical(this,    tr("Could not open"),
                                        tr("Could not open any device because of permission problem.\n"
                                        "Make sure that you have permission to access your fingerprint device \n"
                                        "or run chmod a+rw on the device"),
                                        QMessageBox::Ok);
    }

    // Make the discovered devices free, they are not needed anymore
    fp_dscv_devs_free(discoveredDevices);
    discoveredDevices = NULL;
}

void MainWindow::createDeviceInfo()
{
    QString info = tr("No");
    if(openedDevice != NULL)
    {
        ui->labelDriverName->setText(fp_driver_get_name(deviceDriver));
        ui->labelFullName->setText(fp_driver_get_full_name(deviceDriver));
        ui->labelDriverID->setText(QString::number(fp_driver_get_driver_id(deviceDriver)));
        ui->labelDeviceType->setText(QString::number(fp_dev_get_devtype(openedDevice)));
        ui->labelEnrollStages->setText(QString::number(fp_dev_get_nr_enroll_stages(openedDevice)));
        if(fp_dev_supports_imaging(openedDevice))
            info = tr("Yes");
        ui->labelImageSupport->setText(info);
        if(fp_dev_supports_identification(openedDevice))
            info = tr("Yes");
        ui->labelIdentificationSupport->setText(info);
    }
}

// Show a dialog and start a thread
void MainWindow::enroll(int fingerprint)
{
    delete enrollDialog;
    enrollDialog = NULL;
    enrollDialog = new EnrollDialog(this);
    enrollDialog->show();
    thread->set(openedDevice, fingerprint);
    thread->start();

    connect(thread, SIGNAL(statusChanged(int)), enrollDialog, SLOT(setStatus(int)));
    connect(enrollDialog, SIGNAL(accepted()), this, SLOT(discoverFingerprints()));
    connect(enrollDialog, SIGNAL(rejected()), this, SLOT(discoverFingerprints()));
    connect(enrollDialog, SIGNAL(rejected()), thread, SLOT(quit()));
}

// Create fp_print_data, find and verify the chosen finger and delete fp_print_data
void MainWindow::verify(int fingerprint)
{
    discoverFingerprints();
    qDebug() << "Verifying " << fingerprint;
    int verified = -1;
    struct fp_print_data *data;
    for(int i = 0; i < nrOfDiscoveredFingerprints; i++)
    {
        if(fp_dscv_print_get_finger(discoveredFingerprints[i]) == (fp_finger)fingerprint)
            fp_print_data_from_dscv_print(discoveredFingerprints[i], &data);
    }
    if(data != NULL && openedDevice != NULL)
    {
        verified = fp_verify_finger(openedDevice, data);
        if(verified == FP_VERIFY_MATCH)
            qDebug() << "Verified successfully!";
        for(int i = 0; i < 5; i++)
        {
            if(verified == FP_VERIFY_NO_MATCH)
                qDebug() << "Couldn't verify";
            else if(verified == FP_VERIFY_RETRY)
                qDebug() << "Poor scan quality";
            else if(verified == FP_VERIFY_RETRY_TOO_SHORT)
                qDebug() << "Too short";
            else if(verified == FP_VERIFY_RETRY_CENTER_FINGER)
                qDebug() << "Not centered";
            else if(verified == FP_VERIFY_RETRY_REMOVE_FINGER)
                qDebug() << "Pressure problems";
            verified = fp_verify_finger(openedDevice, data);
        }
    }
    else
    {
        QMessageBox::critical(this, tr("Couldn't verify - QAuthentee"),
                                    tr("Couldn't verify because of fingerprint error!"),
                                    QMessageBox::Ok | QMessageBox::Cancel);
    }
    // Make the fp_print_data free
    fp_print_data_free(data);
    data = NULL;
}

// Remove fingerprint
void MainWindow::remove(int fingerprint)
{
    if(QMessageBox::warning(this,   tr("Remove fingerprint - QAuthentee"),
                                    tr("Are you sure you want remove the chosen fingerprint?"),
                                    QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok)
    {
        if(fp_print_data_delete(openedDevice, (fp_finger)fingerprint) == 0)
        {
            QMessageBox::information(this,  tr("Removed fingerprint - QAuthentee"),
                                            tr("The fingerprint has been removed successfully!"), QMessageBox::Ok);
            ui->displayWidget->markEnrolledFingerprints(fingerprint - 1, false);
        }
        else
        {
            QMessageBox::critical(this,  tr("Error - QAuthentee"),
                                            tr("The fingerprint couldn't be removed!"), QMessageBox::Ok);
        }
    }
}

void MainWindow::removeAll()
{
    if(QMessageBox::warning(this,   tr("Remove all fingerprints - QAuthentee"),
                                    tr("Are you sure you want remove the ALL stored fingerprints?"),
                                    QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok)
    {
        for(int i = 1; i < 11; i++)
        {
            fp_print_data_delete(openedDevice, (fp_finger)i);
            ui->displayWidget->markEnrolledFingerprints(i - 1, false);
        }

        QMessageBox::information(this,  tr("Removed all fingerprints - QAuthentee"),
                                        tr("The fingerprints has been removed successfully!"),
                                        QMessageBox::Ok);
    }

}

//void MainWindow::showDetails(int fingerprint)
//{
//    // TODO BUT HOW?
//}
/*
    if(!ui->actionEnroll->isEnabled())
    {
        ui->actionEnroll->setStatusTip(tr("To enable this menu mark one of the fingers first"));
    }

//
//    fp_print_data *data = NULL;
//    fp_img *image = NULL;
//
//    //qDebug() << fp_dev_get_img_height(openedDevice);
//    for(int i = 0; i < 3; i++)
//    {
//    int enrolled = fp_enroll_finger(openedDevice, &data);
//    if(enrolled == FP_ENROLL_COMPLETE)
//        qDebug() << "Enrolling complete!";
//    else if(enrolled == FP_ENROLL_RETRY)
//        qDebug() << "Retry!";
//    }
//
//    qDebug() << "Right tumb: " << fp_print_data_save(data, LEFT_THUMB);
//    //qDebug() << "Capture: " << fp_dev_img_capture(openedDevice, 0, &image);
//    //qDebug() << "Save pgm: " << fp_img_save_to_file(image, "finger.pgm");
//    //qDebug() << "Height: " << fp_img_get_height(image);
//    //fp_img_standardize(image);
//    //qDebug() << "Save png: " << fp_img_save_to_file(image, "finger_standardized.png");
//
//    fp_print_data_free(data);
//    data = NULL;
//    fp_img_free(image);
//    image = NULL;
*/
